home *** CD-ROM | disk | FTP | other *** search
/ Chip 2000 October / CHIP Turkiye Ekim 2000.iso / prog / naps / 04 / setup.exe / Gnucleus / AnimEffect.cpp next >
C/C++ Source or Header  |  2000-06-17  |  19KB  |  682 lines

  1. // Written by SiGMan / iO UpG  13-04-2000
  2. // 
  3. //
  4. // AnimEffect.cpp: implementation of the AnimEffect class.
  5. //
  6. //////////////////////////////////////////////////////////////////////
  7.  
  8. #define _ANIM_INTERNAL_
  9.  
  10. #include "stdafx.h"
  11. #include "AnimEffect.h"
  12. #include <math.h>
  13.  
  14. #ifdef _DEBUG
  15. #undef THIS_FILE
  16. static char THIS_FILE[]=__FILE__;
  17. #define new DEBUG_NEW
  18. #endif
  19.  
  20. #define FIXED_SHIFT 16
  21. #define FIXED int
  22.  
  23. typedef struct tag_MATRIXF {
  24.     FIXED fM11;
  25.     FIXED fM12;
  26.     int      iM13;
  27.     FIXED fM21;
  28.     FIXED fM22;
  29.     int   iM23;
  30.     int   iM31;
  31.     int   iM32;
  32.     int   iM33;
  33. } MATRIXF;
  34.  
  35. const FIXED fixed1= 1 << FIXED_SHIFT;
  36. const MATRIXF matrix1 = { fixed1, 0, 0, 0, fixed1, 0, 0, 0, 1 };
  37. const POINT point0 = { 0, 0 };
  38.  
  39. int        fixedMul(int iMultiplicand, FIXED fMultiplier);
  40. FIXED    fixedDiv(int iNumerator, int iDenominator);
  41. POINT    operator*( const POINT &point, const MATRIXF &matrix);
  42. MATRIXF    operator*( const MATRIXF &matrix1, const MATRIXF &matrix2);
  43. MATRIXF    mix( const MATRIXF &matrix1, const MATRIXF &matrix2, FIXED fMix);
  44. POINT    mix( const POINT &point1, const POINT &point2, FIXED fMix);
  45.  
  46. MATRIXF scaleMatrix( FIXED scaleX, FIXED scaleY, POINT ptOrg = point0 );
  47. MATRIXF rotateMatrix( FIXED angle, POINT ptOrg = point0 );
  48. MATRIXF offsetMatrix( int offsetX, int offsetY );
  49.  
  50. BOOL    efSpinFrame( AnimData *pAnimData );
  51. BOOL    efVortexFrames( AnimData *pAnimData );
  52. BOOL    efScatterGatherFrames( AnimData *pAnimData );
  53. BOOL    efSpikeFrames( AnimData *pAnimData );
  54. BOOL    efFireworxFrames( AnimData *pAnimData );
  55.  
  56.  
  57.  
  58. inline POINT operator+(POINT &point1, POINT &point2)
  59. {
  60.     POINT ptResult;
  61.     ptResult.x = point1.x + point2.x;
  62.     ptResult.y = point1.y + point2.y;
  63.     return ptResult;
  64. }
  65.  
  66. inline POINT operator-(POINT &point1, POINT &point2)
  67. {
  68.     POINT ptResult;
  69.     ptResult.x = point1.x - point2.x;
  70.     ptResult.y = point1.y - point2.y;
  71.     return ptResult;
  72. }
  73.  
  74. inline MATRIXF& operator *=(MATRIXF &matrix1, const MATRIXF &matrix2)
  75. {
  76.     return matrix1 = matrix1*matrix2;
  77. }
  78.  
  79.  
  80. void drawBox( HDC hDC, POINT &ptCenter, POINT &ptRelRightTop );
  81. void drawPoly( HDC hDC, POINT *pPts, DWORD dwPoints );
  82.  
  83. //////////////////////////////////////////////////////////////////////
  84. // Construction/Destruction
  85. //////////////////////////////////////////////////////////////////////
  86.  
  87. AnimEffect::AnimEffect()
  88. {
  89.     m_hDC = ::GetDC(NULL);
  90.     m_hPen = ::CreatePen( PS_SOLID, 1, RGB(0,0,0) );
  91.  
  92.     Defaults();
  93. }
  94.  
  95. AnimEffect::~AnimEffect()
  96. {
  97.     ::DeleteObject( m_hPen );
  98.     ::ReleaseDC( NULL, m_hDC );
  99. }
  100.  
  101. void AnimEffect::Defaults()
  102. {
  103.     m_rcScreen = CRect(0,0,GetSystemMetrics(SM_CXFULLSCREEN),GetSystemMetrics(SM_CYFULLSCREEN));
  104.     m_iAfterimages = 6;
  105.     m_iTotalSteps = 50;
  106.     m_iDelay = 5;
  107.     Effect( Random );
  108. }
  109.  
  110. void AnimEffect::Setup(int iSteps, int iAfterimages, int iDelay)
  111. {
  112.     if (iSteps > 255) iSteps = 255;
  113.     else if (iSteps < 1) iSteps = 1;
  114.     m_iTotalSteps = iSteps;
  115.  
  116.     if (iAfterimages > 32) iAfterimages = 32;
  117.     else if (iAfterimages < 0) iAfterimages = 0;
  118.     m_iAfterimages = iAfterimages;
  119.  
  120.     if (iDelay > 100) iDelay = 100;
  121.     else if (iDelay < 0) iDelay = 0;
  122. }
  123.  
  124. void AnimEffect::Effect( EffectType effect )
  125. {
  126.     switch ( effect ) {
  127.     case Random:
  128.         break;
  129.     case Spin:
  130.         m_iParameter = 360;
  131.         break;
  132.     case Vortex:
  133.         m_iParameter = 180;
  134.         break;
  135.     case ScatterGather:
  136.         m_iParameter = 4;
  137.         break;
  138.     case Spike:
  139.         m_iParameter = 180;
  140.         break;
  141.     case Fireworks:
  142.         m_iParameter = 360;
  143.         break;
  144.     }
  145.     m_Effect = effect;
  146. }
  147.  
  148. void AnimEffect::ChooseFunc()
  149. {
  150.     bool bRandom = false;
  151.  
  152.     if (m_Effect == Random) {
  153.         bRandom = true;
  154.         Effect((EffectType)(rand() % 5));
  155.     }
  156.  
  157.     switch (m_Effect) {
  158.     case Spin:
  159.         m_Func = efSpinFrame;
  160.         break;
  161.     case Vortex:
  162.         m_Func = efVortexFrames;
  163.         break;
  164.     case ScatterGather:
  165.         m_Func = efScatterGatherFrames;
  166.         break;
  167.     case Spike:
  168.         m_Func = efSpikeFrames;
  169.         break;
  170.     case Fireworks:
  171.         m_Func = efFireworxFrames;
  172.         break;
  173.     default:
  174.         m_Func = 0;
  175.     }
  176.  
  177.     if (bRandom) {
  178.         m_Effect = Random;
  179.     }
  180. }
  181.  
  182.  
  183. void AnimEffect::Open( const CRect &rcWnd )
  184. {
  185.     HPEN oldpen;
  186.     int     oldrop2;
  187.     AnimData ad;
  188.  
  189.     oldpen = (HPEN)::SelectObject(m_hDC, m_hPen);
  190.     oldrop2= ::SetROP2(m_hDC, R2_NOT);
  191.  
  192.     ChooseFunc();
  193.     ad.bOpen = TRUE;
  194.     ad.hDC = m_hDC;
  195.     ad.iAfterimages = m_iAfterimages;
  196.     ad.iTotalSteps = m_iTotalSteps;
  197.     ad.rcWnd = rcWnd;
  198.     ad.ptCenter = rcWnd.CenterPoint();
  199.     ad.ptRelRightTop = CPoint( rcWnd.right - ad.ptCenter.x,rcWnd.top - ad.ptCenter.y );
  200.     ad.iParameter = m_iParameter;
  201.  
  202.     Animate(ad);
  203.     
  204.     ::SetROP2(m_hDC, oldrop2);
  205.     ::SelectObject(m_hDC, oldpen);
  206. }
  207.  
  208. void AnimEffect::Close( const CRect &rcWnd )
  209. {
  210.     HPEN oldpen;
  211.     int     oldrop2;
  212.     AnimData ad;
  213.  
  214.     oldpen = (HPEN)::SelectObject(m_hDC, m_hPen);
  215.     oldrop2= ::SetROP2(m_hDC, R2_NOT);
  216.  
  217.     ChooseFunc();
  218.     ad.bOpen = FALSE;
  219.     ad.hDC = m_hDC;
  220.     ad.iAfterimages = m_iAfterimages;
  221.     ad.iTotalSteps = m_iTotalSteps;
  222.     ad.rcWnd = rcWnd;
  223.     ad.ptCenter = rcWnd.CenterPoint();
  224.     ad.ptRelRightTop = CPoint( rcWnd.right - ad.ptCenter.x,rcWnd.top - ad.ptCenter.y );
  225.     ad.iParameter = m_iParameter;
  226.  
  227.     Animate(ad);
  228.     
  229.     ::SetROP2(m_hDC, oldrop2);
  230.     ::SelectObject(m_hDC, oldpen);
  231. }
  232.  
  233. void AnimEffect::Animate(AnimData &animData)
  234. {
  235.     animData.animType = AnimInit;
  236.     m_Func(&animData);
  237.  
  238.     if (animData.bOpen) {
  239.         for(int frame=0;frame < animData.iTotalSteps+animData.iAfterimages;frame++) {
  240.             // draw 
  241.             if (frame < animData.iTotalSteps) {
  242.                 animData.animType = AnimDraw;
  243.                 animData.iStep = frame;
  244.                 m_Func( &animData );
  245.                 ::GdiFlush();
  246.             }
  247.             Sleep(m_iDelay);
  248.             // erase
  249.             if (frame >= animData.iAfterimages) {
  250.                 animData.animType = AnimErase;
  251.                 animData.iStep = frame - animData.iAfterimages;
  252.                 m_Func( &animData );
  253.                 ::GdiFlush();
  254.             }
  255.         }
  256.     } else {
  257.         for(int frame=animData.iTotalSteps+animData.iAfterimages-1;frame >= 0 ;frame--) {
  258.             // draw 
  259.             if (frame >= animData.iAfterimages) {
  260.                 animData.animType = AnimDraw;
  261.                 animData.iStep = frame - animData.iAfterimages;
  262.                 m_Func( &animData );
  263.                 ::GdiFlush();
  264.             }
  265.             Sleep(m_iDelay);
  266.             // erase
  267.             if (frame < animData.iTotalSteps) {
  268.                 animData.animType = AnimErase;
  269.                 animData.iStep = frame;
  270.                 m_Func( &animData );
  271.                 ::GdiFlush();
  272.             }
  273.         }
  274.     }
  275.  
  276.     animData.animType = AnimTerm;
  277.     m_Func(&animData);
  278. }
  279. //////////////////////////////////////////////////////////////////////
  280. // Supp. functions
  281. //////////////////////////////////////////////////////////////////////
  282.  
  283. int        fixedMul(int iMultiplicand, FIXED fMultiplier)
  284. {
  285.     return MulDiv(iMultiplicand, fMultiplier, 65536);
  286. }
  287.  
  288. FIXED    fixedDiv(int iNumerator, int iDenominator)
  289. {
  290.     if ( iNumerator == 0 || iDenominator == 0) return 0;
  291.  
  292.     return MulDiv(65536,iNumerator,iDenominator);
  293. }
  294.  
  295. POINT    operator*( const POINT &point, const MATRIXF &matrix)
  296. {
  297.     POINT ptResult;
  298.     ptResult.x = fixedMul(point.x, matrix.fM11) + fixedMul(point.y,matrix.fM21) + matrix.iM31;
  299.     ptResult.y = fixedMul(point.x, matrix.fM12) + fixedMul(point.y,matrix.fM22) + matrix.iM32;
  300.     return ptResult;
  301. }
  302.  
  303. MATRIXF    operator*( const MATRIXF &m1, const MATRIXF &m2)
  304. {
  305.     MATRIXF mtRes;
  306.  
  307.     mtRes.fM11 = fixedMul(m1.fM11,m2.fM11) + fixedMul(m1.fM12,m2.fM21);
  308.     mtRes.fM12 = fixedMul(m1.fM11,m2.fM12) + fixedMul(m1.fM12,m2.fM22);
  309.     mtRes.iM13 = 0;
  310.     mtRes.fM21 = fixedMul(m1.fM21,m2.fM11) + fixedMul(m1.fM22,m2.fM21);
  311.     mtRes.fM22 = fixedMul(m1.fM21,m2.fM12) + fixedMul(m1.fM22,m2.fM22);
  312.     mtRes.iM23 = 0;
  313.     mtRes.iM31 = fixedMul(m1.iM31,m2.fM11) + fixedMul(m1.iM32,m2.fM21) + m2.iM31;
  314.     mtRes.iM32 = fixedMul(m1.iM31,m2.fM12) + fixedMul(m1.iM32,m2.fM22) + m2.iM32;
  315.     mtRes.iM33 = 1;
  316.  
  317.     return mtRes;
  318. }
  319.  
  320. MATRIXF    mix( const MATRIXF &matrix1, const MATRIXF &matrix2, FIXED fMix)
  321. {
  322.     MATRIXF mtRes;
  323.  
  324.     mtRes.fM11 = fixedMul(matrix1.fM11, fMix) + fixedMul(matrix2.fM11,fixed1-fMix);
  325.     mtRes.fM12 = fixedMul(matrix1.fM12, fMix) + fixedMul(matrix2.fM12,fixed1-fMix);
  326.     mtRes.iM13 = fixedMul(matrix1.iM13, fMix) + fixedMul(matrix2.iM13,fixed1-fMix);
  327.     mtRes.fM21 = fixedMul(matrix1.fM21, fMix) + fixedMul(matrix2.fM21,fixed1-fMix);
  328.     mtRes.fM22 = fixedMul(matrix1.fM22, fMix) + fixedMul(matrix2.fM22,fixed1-fMix);
  329.     mtRes.iM23 = fixedMul(matrix1.iM23, fMix) + fixedMul(matrix2.iM23,fixed1-fMix);
  330.     mtRes.iM31 = fixedMul(matrix1.iM31, fMix) + fixedMul(matrix2.iM31,fixed1-fMix);
  331.     mtRes.iM32 = fixedMul(matrix1.iM32, fMix) + fixedMul(matrix2.iM32,fixed1-fMix);
  332.     mtRes.iM33 = fixedMul(matrix1.iM33, fMix) + fixedMul(matrix2.iM33,fixed1-fMix);
  333.  
  334.     return mtRes;
  335. }
  336.  
  337. POINT    mix( const POINT &point1, const POINT &point2, FIXED fMix)
  338. {
  339.     POINT ptRes;
  340.  
  341.     ptRes.x = fixedMul(point1.x,fMix) + fixedMul(point2.x,fixed1-fMix);
  342.     ptRes.y = fixedMul(point1.y,fMix) + fixedMul(point2.y,fixed1-fMix);
  343.  
  344.     return ptRes;
  345. }
  346.  
  347. MATRIXF offsetMatrix( int offsetX, int offsetY )
  348. {
  349.     MATRIXF mRes = matrix1;
  350.  
  351.     mRes.iM31 = offsetX;
  352.     mRes.iM32 = offsetY;
  353.  
  354.     return mRes;
  355. }
  356.  
  357. MATRIXF scaleMatrix( FIXED scaleX, FIXED scaleY, POINT ptOrg)
  358. {
  359.     MATRIXF mRes = matrix1;
  360.  
  361.     mRes.fM11 = scaleX;
  362.     mRes.fM22 = scaleY;
  363.  
  364.     return offsetMatrix(-ptOrg.x,-ptOrg.y) * mRes * offsetMatrix(ptOrg.x,ptOrg.y);
  365. }
  366.  
  367. MATRIXF rotateMatrix( FIXED angle, POINT ptOrg)
  368. {
  369.     MATRIXF mRes = matrix1;
  370.  
  371.     double dAngle = (angle / 65536.0) * 3.141592654 / 180.0;
  372.     FIXED fCos = (FIXED)(65536.0 * cos( dAngle ));
  373.     FIXED fSin = (FIXED)(65536.0 * sin( dAngle ));
  374.  
  375.     mRes.fM11 =  fCos;
  376.     mRes.fM21 =  -fSin;
  377.     mRes.fM12 =  fSin;
  378.     mRes.fM22 =  fCos;
  379.  
  380.     return offsetMatrix(-ptOrg.x,-ptOrg.y) * mRes * offsetMatrix(ptOrg.x,ptOrg.y);
  381. }
  382.  
  383. /////////////////////////////////////////////////////////
  384. // Effects
  385. /////////////////////////////////////////////////////////
  386. BOOL    efSpinFrame( AnimData *pAnimData )
  387. {
  388.     if (pAnimData->animType == AnimDraw ||
  389.         pAnimData->animType == AnimErase ) {
  390.         POINT ptRect[4];
  391.  
  392.         ptRect[1].x = ptRect[0].x = pAnimData->ptRelRightTop.x;
  393.         ptRect[1].y = -(ptRect[0].y = pAnimData->ptRelRightTop.y);
  394.  
  395.         MATRIXF matrix;
  396.         FIXED    fxScale;
  397.         fxScale = fixedDiv(pAnimData->iStep,pAnimData->iTotalSteps);
  398.  
  399.         matrix = scaleMatrix( fxScale, fxScale ) *     rotateMatrix( 
  400.             fixedDiv( pAnimData->iParameter * ( pAnimData->iStep - pAnimData->iTotalSteps ), pAnimData->iTotalSteps ) );
  401.  
  402.         ptRect[0] = ptRect[0] * matrix;
  403.         ptRect[1] = ptRect[1] * matrix;
  404.         ptRect[2] = pAnimData->ptCenter + ptRect[0];
  405.         ptRect[3] = pAnimData->ptCenter + ptRect[1];
  406.         ptRect[0] = pAnimData->ptCenter - ptRect[0];
  407.         ptRect[1] = pAnimData->ptCenter - ptRect[1];
  408.  
  409.         drawPoly(pAnimData->hDC,ptRect,4);
  410.     }
  411.  
  412.     return TRUE;
  413. }
  414.  
  415. BOOL efVortexFrames( AnimData *pAnimData )
  416. {
  417.     switch ( pAnimData->animType ) {
  418.         case AnimInit :
  419.             *(MATRIXF*)pAnimData->bBuffer = rotateMatrix( fixed1 * 72 , pAnimData->ptCenter);
  420.             break;
  421.         case AnimDraw:
  422.         case AnimErase: 
  423.             {
  424.                 POINT ptBoxRel;
  425.  
  426.                 ptBoxRel.x = pAnimData->ptRelRightTop.x * pAnimData->iStep / pAnimData->iTotalSteps;
  427.                 ptBoxRel.y = pAnimData->ptRelRightTop.y * pAnimData->iStep / pAnimData->iTotalSteps;
  428.  
  429.                 MATRIXF matrix;
  430.                 FIXED    fxScale;
  431.  
  432.                 fxScale = fixedDiv( (pAnimData->iTotalSteps - pAnimData->iStep) * 4,
  433.                     pAnimData->iTotalSteps * 3 );
  434.                 
  435.                 matrix = offsetMatrix( pAnimData->ptRelRightTop.x, pAnimData->ptRelRightTop.y ) *
  436.                       scaleMatrix( fxScale, fxScale, pAnimData->ptCenter ) *
  437.                       rotateMatrix( fixedDiv(pAnimData->iParameter * pAnimData->iStep, pAnimData->iTotalSteps) , pAnimData->ptCenter );
  438.  
  439.                 POINT ptBoxCenter;
  440.                 ptBoxCenter = pAnimData->ptCenter * matrix;
  441.  
  442.                 for( int iLoop = 0; iLoop < 5; iLoop++) {
  443.                     drawBox( pAnimData->hDC, ptBoxCenter, ptBoxRel );
  444.                     ptBoxCenter = ptBoxCenter * *(MATRIXF *)pAnimData->bBuffer;
  445.                 }
  446.  
  447.                 break;
  448.             }
  449.     }
  450.  
  451.     return TRUE;
  452. }
  453.  
  454. BOOL efScatterGatherFrames( AnimData *pAnimData )
  455. {
  456.     if ( pAnimData->animType == AnimDraw ||
  457.         pAnimData->animType == AnimErase ) {
  458.         int iDivisor = pAnimData->iParameter;
  459.         POINT ptBoxRel;
  460.  
  461.         ptBoxRel.x = pAnimData->ptRelRightTop.x *  pAnimData->iStep / (pAnimData->iTotalSteps * iDivisor);
  462.         ptBoxRel.y = pAnimData->ptRelRightTop.y *  pAnimData->iStep / (pAnimData->iTotalSteps * iDivisor);
  463.  
  464.         MATRIXF matrix;
  465.         FIXED fxScale;
  466.  
  467.         fxScale = fixedDiv( pAnimData->iTotalSteps * 3 - pAnimData->iStep * 2, pAnimData->iTotalSteps );
  468.         matrix = scaleMatrix( fxScale, fxScale ) * offsetMatrix( pAnimData->ptCenter.x, pAnimData->ptCenter.y );
  469.  
  470.         for(int iRow = 0; iRow < iDivisor; iRow++) {
  471.             for( int iCol=0; iCol < iDivisor; iCol++) {
  472.                 POINT ptTileCenter;
  473.  
  474.                 ptTileCenter.x = (iRow * 2 - iDivisor + 1) * pAnimData->ptRelRightTop.x / iDivisor;
  475.                 ptTileCenter.y = (iCol * 2 - iDivisor + 1) * pAnimData->ptRelRightTop.y / iDivisor;
  476.                 ptTileCenter = ptTileCenter * matrix;
  477.  
  478.                 drawBox( pAnimData->hDC, ptTileCenter, ptBoxRel );
  479.             }
  480.         }
  481.     }
  482.  
  483.     return TRUE;
  484. }
  485.  
  486. BOOL efSpikeFrames( AnimData *pAnimData )
  487. {
  488.     struct SpikeData {
  489.         POINT ptTriangleEnd[16][3], ptEndCenter[16], ptTriangleCenter[16];
  490.         MATRIXF matrixCircle[16];
  491.     };
  492.  
  493.     switch (pAnimData->animType) {
  494.     case AnimInit: {
  495.         int xLeft    = pAnimData->rcWnd.left;
  496.         int xRight    = pAnimData->rcWnd.right;
  497.         int yTop    = pAnimData->rcWnd.bottom;
  498.         int yBottom = pAnimData->rcWnd.top;
  499.  
  500.         POINT *pTriangle = ((SpikeData*)pAnimData->bBuffer)->ptTriangleEnd[0],
  501.               *pCenter     = ((SpikeData*)pAnimData->bBuffer)->ptEndCenter;
  502.         
  503.         for( int iNdx = 0; iNdx < 16; iNdx++, pTriangle +=3, pCenter++) {
  504.             pTriangle[0] = pAnimData->ptCenter;
  505.  
  506.             if (iNdx < 4) {
  507.                 pTriangle[1].y = pTriangle[2].y = yTop;
  508.                 pTriangle[1].x = (xLeft * (4 - iNdx) + xRight * iNdx) / 4;
  509.                 pTriangle[2].x = (xLeft * (3 - iNdx) + xRight * (iNdx+1)) / 4;
  510.             } else if (iNdx < 8) {
  511.                 pTriangle[1].x = pTriangle[2].x = xRight;
  512.                 pTriangle[1].y = (yTop * (8 - iNdx) + yBottom * (iNdx-4)) / 4;
  513.                 pTriangle[2].y = (yTop * (7 - iNdx) + yBottom * (iNdx-3)) / 4;
  514.             } else if (iNdx < 12) {
  515.                 pTriangle[1].y = pTriangle[2].y = yBottom;
  516.                 pTriangle[1].x = (xRight * (12 - iNdx) + xLeft * (iNdx-8)) / 4;
  517.                 pTriangle[2].x = (xRight * (11 - iNdx) + xLeft * (iNdx-7)) / 4;
  518.             } else {
  519.                 pTriangle[1].x = pTriangle[2].x = xLeft;
  520.                 pTriangle[1].y = (yBottom * (16 - iNdx) + yTop * (iNdx-12)) / 4;
  521.                 pTriangle[2].y = (yBottom * (15 - iNdx) + yTop * (iNdx-11)) / 4;
  522.             }
  523.  
  524.             pCenter->x = (pTriangle[0].x + pTriangle[1].x + pTriangle[2].x) / 3;
  525.             pCenter->y = (pTriangle[0].y + pTriangle[1].y + pTriangle[2].y) / 3;
  526.         }
  527.  
  528.         pCenter = ((SpikeData*)pAnimData->bBuffer)->ptTriangleCenter;
  529.         POINT ptTrgCenter;
  530.  
  531.         ptTrgCenter.x = pAnimData->ptCenter.x;
  532.         ptTrgCenter.y = pAnimData->ptCenter.y + (pAnimData->ptRelRightTop.x + pAnimData->ptRelRightTop.y) * 4/5;
  533.  
  534.         for( iNdx =0;iNdx < 16; iNdx++ ) {
  535.             MATRIXF matrix;
  536.  
  537.             matrix = rotateMatrix( (33 * fixed1) + (-22 * fixed1) * iNdx, pAnimData->ptCenter );
  538.             pCenter[iNdx] = ptTrgCenter * matrix;
  539.  
  540.             POINT ptTemp = pCenter[iNdx] - ((SpikeData*)pAnimData->bBuffer)->ptEndCenter[iNdx];
  541.             ((SpikeData*)pAnimData->bBuffer)->matrixCircle[iNdx] = offsetMatrix( ptTemp.x, ptTemp.y );
  542.         }
  543.  
  544.         break;
  545.     }
  546.     case AnimDraw:
  547.     case AnimErase: {
  548.         POINT ptTriangle[3];
  549.         FIXED fixedFactor;
  550.  
  551.         MATRIXF matrix;
  552.         FIXED fxScale;
  553.         fxScale = fixedDiv(pAnimData->iStep, pAnimData->iTotalSteps);
  554.  
  555.         if (pAnimData->iStep < pAnimData->iTotalSteps / 2) {
  556.             fixedFactor = (fixed1 - fixedDiv(pAnimData->iStep*2, pAnimData->iTotalSteps)) *
  557.                 pAnimData->iParameter;
  558.  
  559.             for( int iNdx=0;iNdx < 16; iNdx++ ) {
  560.                 matrix = scaleMatrix( fxScale, fxScale, ((SpikeData*)pAnimData->bBuffer)->ptEndCenter[iNdx] ) *
  561.                     rotateMatrix( fixedFactor, ((SpikeData*)pAnimData->bBuffer)->ptEndCenter[iNdx] );
  562.                 matrix = matrix * ((SpikeData*)pAnimData->bBuffer)->matrixCircle[iNdx];
  563.  
  564.                 for(int iAngle=0;iAngle < 3;iAngle++) {
  565.                     ptTriangle[iAngle] = 
  566.                         ((SpikeData*)pAnimData->bBuffer)->ptTriangleEnd[iNdx][iAngle] * matrix;
  567.                 }
  568.  
  569.                 drawPoly( pAnimData->hDC, ptTriangle, 3 );
  570.             }
  571.         } else {
  572.             fixedFactor = fixedDiv(pAnimData->iStep*2 - pAnimData->iTotalSteps, pAnimData->iTotalSteps);
  573.  
  574.             for( int iNdx=0; iNdx < 16; iNdx++) {
  575.                 matrix = scaleMatrix( fxScale, fxScale, ((SpikeData*)pAnimData->bBuffer)->ptEndCenter[iNdx]);
  576.                 matrix *= mix( matrix1, ((SpikeData*)pAnimData->bBuffer)->matrixCircle[iNdx], fixedFactor );
  577.  
  578.                 for( int iAngle=0; iAngle < 3; iAngle++ ) {
  579.                     ptTriangle[iAngle] = 
  580.                         ((SpikeData*)pAnimData->bBuffer)->ptTriangleEnd[iNdx][iAngle] * matrix;
  581.                 }
  582.  
  583.                 drawPoly(pAnimData->hDC, ptTriangle, 3 );
  584.             }
  585.         }
  586.  
  587.  
  588.         break;
  589.     }
  590.     }
  591.  
  592.     return TRUE;
  593. }
  594.  
  595. BOOL efFireworxFrames( AnimData *pAnimData )
  596. {
  597.     const int NRECT = 10;
  598.     struct FWData {
  599.         POINT ptCenter[NRECT];
  600.     };
  601.  
  602.     switch ( pAnimData->animType ) {
  603.     case AnimInit: {
  604.         POINT *ptCenter = ((FWData*)pAnimData->bBuffer)->ptCenter;
  605.         POINT ptRectCenter;
  606.         
  607.         ptRectCenter.x = pAnimData->ptCenter.x;
  608.         ptRectCenter.y = pAnimData->ptCenter.y + (pAnimData->ptRelRightTop.x + pAnimData->ptRelRightTop.y) * 5/3;
  609.  
  610.         for(int iNdx=0;iNdx < NRECT;iNdx++) {
  611.             MATRIXF matrix = rotateMatrix( iNdx * (360 * fixed1 / NRECT), pAnimData->ptCenter );
  612.  
  613.             ptCenter[iNdx] = ptRectCenter * matrix;
  614.             
  615.         }
  616.         break;
  617.     }
  618.     case AnimDraw:
  619.     case AnimErase: {
  620.         POINT ptTemp;
  621.         FIXED fixedFactor = fixedDiv( pAnimData->iStep, pAnimData->iTotalSteps );
  622.  
  623.         MATRIXF matrix;
  624.         POINT ptRect[4], ptTmp[4];
  625.         ptRect[0].x = ptRect[3].x = -pAnimData->ptRelRightTop.x;
  626.         ptRect[1].x = ptRect[2].x = pAnimData->ptRelRightTop.x;
  627.         ptRect[0].y = ptRect[1].y = pAnimData->ptRelRightTop.y;
  628.         ptRect[2].y = ptRect[3].y = -pAnimData->ptRelRightTop.y;
  629.  
  630.         for(int iNdx=0; iNdx < NRECT; iNdx++) {
  631.             matrix = scaleMatrix( fixedFactor, fixedFactor ) *
  632.                 rotateMatrix( (fixed1-fixedFactor)*pAnimData->iParameter);
  633.  
  634.             ptTemp = mix(pAnimData->ptCenter, ((FWData*)pAnimData->bBuffer)->ptCenter[iNdx], fixedFactor);
  635.             matrix = matrix * offsetMatrix( ptTemp.x, ptTemp.y );
  636.  
  637.             for(int iAngle=0; iAngle < 4; iAngle++) 
  638.                 ptTmp[iAngle] = ptRect[iAngle] * matrix;
  639.             
  640.             drawPoly( pAnimData->hDC, ptTmp, 4 );
  641.         }
  642.  
  643.         break;
  644.     }
  645.     }
  646.  
  647.     return TRUE;
  648. }
  649.  
  650. /////////////////////////////////////////////////////////
  651. // Primitives
  652. /////////////////////////////////////////////////////////
  653.  
  654. void drawBox( HDC hDC, POINT &ptCenter, POINT &ptRelRightTop )
  655. {
  656.     if (ptRelRightTop.x == 0 && ptRelRightTop.y == 0) return;
  657.  
  658.     POINT ptTemp[4];
  659.  
  660.     ptTemp[0].x = ptCenter.x - ptRelRightTop.x;
  661.     ptTemp[0].y = ptCenter.y + ptRelRightTop.y;
  662.     ptTemp[1].x = ptCenter.x + ptRelRightTop.x;
  663.     ptTemp[1].y = ptCenter.y + ptRelRightTop.y;
  664.     ptTemp[2].x = ptCenter.x + ptRelRightTop.x;
  665.     ptTemp[2].y = ptCenter.y - ptRelRightTop.y;
  666.     ptTemp[3].x = ptCenter.x - ptRelRightTop.x;
  667.     ptTemp[3].y = ptCenter.y - ptRelRightTop.y;
  668.  
  669.     ::MoveToEx( hDC, ptTemp[3].x, ptTemp[3].y , NULL );
  670.     ::PolylineTo( hDC, ptTemp, 4 );
  671. }
  672.  
  673. void drawPoly( HDC hDC, POINT *pPts, DWORD dwPoints )
  674. {
  675.     if (pPts == NULL || dwPoints == 0) return;
  676.  
  677.     if (pPts[dwPoints-1].x == pPts[0].x &&
  678.         pPts[dwPoints-1].y == pPts[0].y ) return;
  679.     ::MoveToEx(hDC, pPts[dwPoints-1].x,pPts[dwPoints-1].y,NULL);
  680.     ::PolylineTo( hDC, pPts, dwPoints );
  681. }
  682.